package com.ziven.common.widget.setting;

import android.text.TextUtils;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.PopupMenu;

import com.ziven.common.widget.R;
import com.ziven.common.widget.value.Title;
import com.ziven.common.widget.value.Value;
import com.ziven.common.widget.window.CommonMenu;
import com.ziven.common.widget.value.Image;
import com.ziven.easygo.util.EasyUtils;
import com.ziven.easygo.util.Nulls;
import com.ziven.easygo.util.ResourceUtils;
import com.ziven.easygo.util.Standard;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Ziven
 */
public class MenuPreferenceItem extends BasePreferenceItem
        implements PopupMenu.OnMenuItemClickListener   {

    private CommonMenu menu;
    private final List<TypeMenu> typeMenus;
    private PopupMenu.OnMenuItemClickListener menuItemClickListener;
    private PopupMenu.OnDismissListener dismissListener;
    private int gravity = Gravity.NO_GRAVITY;
    private int styleId = R.style.Common_Widget_PopupMenu;
    private boolean isAutoShowSubTitle = true;
    private boolean isSaveClickItemId = true;

    public MenuPreferenceItem() {
        subIcon = Image.drawableId(R.drawable.drawable_setting_item_bottom_go);
        typeMenus = new ArrayList<>();
    }

    @Override
    public Value effect() {
        if(isAutoShowSubTitle) {
            subTitle2 = Title.title(getString());
        }
        return super.effect();
    }

    @Override
    public void afterDataLoaded() {
        if(isAutoShowSubTitle) {
            setRelatedIds(id);
        }
    }

    public void setAutoShowSubTitle(boolean auto) {
        isAutoShowSubTitle = auto;
    }

    public void setSaveClickItemId(boolean save) {
        isSaveClickItemId = save;
    }

    private MenuPreferenceItem typeMenu(@NonNull TypeMenu typeMenu) {
        typeMenus.add(typeMenu);
        return this;
    }

    public MenuPreferenceItem menu(@NonNull TypeMenu typeMenu) {
        return typeMenu(typeMenu);
    }

    public MenuPreferenceItem menu(@NonNull String title) {
        return menu(new TypeMenu(title));
    }

    public MenuPreferenceItem menu(@StringRes int titleId) {
        return menu(ResourceUtils.getText(titleId));
    }

    public MenuPreferenceItem subTypeMenu(@NonNull String title, @NonNull TypeMenu... typeMenus) {
        return subMenu(new TypeMenu(title).accept(my -> my.subTypeMenu(typeMenus)));
    }

    public MenuPreferenceItem subTypeMenu(@NonNull String title, @NonNull List<TypeMenu> typeMenus) {
        return subMenu(new TypeMenu(title).accept(my -> my.subTypeMenu(typeMenus)));
    }

    public MenuPreferenceItem subMenu(@NonNull String title, @NonNull List<String> subTitles) {
        return subMenu(new TypeMenu(title).accept(my -> EasyUtils.forEach(subTitles, my::subTitle)));
    }

    public MenuPreferenceItem subMenu(@NonNull TypeMenu typeMenu) {
        return typeMenu(typeMenu);
    }

    public MenuPreferenceItem listener(PopupMenu.OnMenuItemClickListener listener) {
        menuItemClickListener = listener;
        return this;
    }

    public MenuPreferenceItem listener(PopupMenu.OnDismissListener listener) {
        dismissListener = listener;
        return this;
    }

    public MenuPreferenceItem setGravity(int gravity) {
        this.gravity = gravity;
        return this;
    }

    public MenuPreferenceItem setStyle(int styleId) {
        this.styleId = styleId;
        return this;
    }

    public void showMenu(@NonNull View view) {
        if(menu != null) {
            menu.dismiss();
        }
        menu = new CommonMenu(view, styleId)
                .listener(isAutoShowSubTitle ? this : menuItemClickListener)
                .listener(value -> {
                    if(dismissListener != null) {
                        dismissListener.onDismiss(value);
                    }
                    menu = null;
                })
                .setGravity(gravity)
                .accept(my -> EasyUtils.forEach(typeMenus,
                        typeMenu -> {
                            if(typeMenu.isSubTitle()) {
                                SubMenu subMenu = my.subMenu(typeMenu.title);
                                EasyUtils.forEach(typeMenu.subTypeMenus, sub -> subMenu.add(sub.groupId, sub.itemId, sub.order, sub.title));
                            } else {
                                my.menu(typeMenu.groupId, typeMenu.itemId, typeMenu.order, typeMenu.title);
                            }
                        }));
        menu.show();
    }

    public Nulls<CommonMenu> menuNull() {
        return Nulls.of(menu);
    }

    public static class TypeMenu implements Standard {

        public final String title;
        public int groupId = 0;
        public int itemId = 0;
        public int order = 0;
        public final List<TypeMenu> subTypeMenus;

        public TypeMenu(@NonNull String title) {
            this.title = title;
            subTypeMenus = new ArrayList<>();
        }

        public TypeMenu setGroupId(int groupId) {
            this.groupId = groupId;
            return this;
        }

        public TypeMenu setItemId(int itemId) {
            this.itemId = itemId;
            return this;
        }

        public TypeMenu setOrder(int order) {
            this.order = order;
            return this;
        }

        public TypeMenu subTypeMenu(@NonNull TypeMenu... menus) {
            EasyUtils.forEach(menus, menu -> subTypeMenus.add(menu));
            return this;
        }

        public TypeMenu subTypeMenu(@NonNull List<TypeMenu> menus) {
            subTypeMenus.addAll(menus);
            return this;
        }

        public TypeMenu subItemId(@NonNull String subTitle, int itemId) {
            subTypeMenus.add(new TypeMenu(subTitle).setItemId(itemId));
            return this;
        }

        public TypeMenu subTitle(@NonNull String subTitle) {
            subTypeMenus.add(new TypeMenu(subTitle));
            return this;
        }

        public TypeMenu subItemId(@StringRes int subTitleId, int itemId) {
            return subItemId(ResourceUtils.getText(subTitleId), itemId);
        }

        public TypeMenu subTitle(@StringRes int subTitleId) {
            return subTitle(ResourceUtils.getText(subTitleId));
        }

        public boolean isSubTitle() {
            return !subTypeMenus.isEmpty();
        }
    }

    @Override
    public boolean onItemClick(BasePreferenceItem data, int position, @NonNull View view) {
        View child = view.findViewById(R.id.sub_icon);
        showMenu(child == null ? view : child);
        return true;
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        if(isAutoShowSubTitle) {
            putString((String) item.getTitle());
        }
        if(isSaveClickItemId && !TextUtils.isEmpty(getId())) {
            putInteger(getId() + "_id", item.getItemId());
        }
        return menuItemClickListener != null && menuItemClickListener.onMenuItemClick(item);
    }
}
